-- vim: ts=4 sw=4 tw=80 noet
local S
if minetest.get_modpath("intllib") then
	S = intllib.Getter()
else
	S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end
end

-- Electronic engine
local loco_def = {
	mesh="advtrains_engine_electronic.b3d",
	textures = {"advtrains_engine_electronic.png"},
	drives_on={default=true},
	max_speed=15,
	seats = {
		{
			name=S("Driver Stand (front)"),
			attach_offset={x=0, y=-1, z=10},
			view_offset={x=0, y=-1, z=0},
			group = "dstand_f",
		},
		{
			name=S("Driver Stand (back)"),
			attach_offset={x=0, y=-1, z=-10},
			view_offset={x=0, y=-1, z=0},
			group = "dstand_b",
			advtrains_attachment_offset_patch_attach_rotation = vector.new(0, 180, 0),
		},
	},
	seat_groups = {
		dstand_f={
			name = S("Driver Stand (front)"),
			access_to = {"dstand_b"},
			require_doors_open=false,
			driving_ctrl_access=true
		},
		dstand_b={
			name = S("Driver Stand (back)"),
			access_to = {"dstand_f"},
			require_doors_open=false,
			driving_ctrl_access=true
		},
	},
	assign_to_seat_group = {"dstand_f", "dstand_b"},
	wagon_span=2.1,
	visual_size = {x=1, y=1},
	collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
	is_locomotive=true,
	drops={"advtrains:engine_electronic"},
	horn_sound = "advtrains_engine_diesel_horn",
	custom_on_velocity_change = function(self, velocity, old_velocity, dtime)
		if not velocity or not old_velocity then return end
		if old_velocity == 0 and velocity > 0 then
			minetest.sound_play("advtrains_train_orient_express_engine_throttle", {object = self.object})
		end
	end

} 

if advtrains_attachment_offset_patch then
	advtrains_attachment_offset_patch.setup_advtrains_wagon(loco_def)
end

advtrains.register_wagon("engine_electronic", loco_def,
	S("Orient Express Electronic Engine"), "advtrains_engine_electronic_inv.png")

local compartment_basic_seats = {
	{
		name="1",
		attach_offset={x=2, y=-1, z=6},
		view_offset={x=0, y=-4, z=0},
		group="pass",
	},
	{
		name="2",
		attach_offset={x=-1, y=-1, z=6},
		view_offset={x=0, y=-4, z=0},
		group="pass",
	},
	{
		name="3",
		attach_offset={x=-4, y=-1, z=-9},
		view_offset={x=0, y=0, z=0},
		group="pass",
	},
	{
		name="4",
		attach_offset={x=4, y=-1, z=-9},
		view_offset={x=0, y=0, z=0},
		group="pass",
	},
}

local compartment_basic_seat_groups = {
	pass = {
		name = "Passenger area",
		access_to = {},
	},
}

-- Compartment wagon
local compartment_def = {
	mesh="advtrains_wagon_compartment.b3d",
	textures = {"advtrains_compartment.png"},
	drives_on={default=true},
	max_speed=15,
	-- The seat positions must fit within the wagon's collision box unless
	-- attachment offset patch is used, same for following wagons in this mod.
	seats = table.copy(compartment_basic_seats),
	seat_groups = table.copy(compartment_basic_seat_groups),
	assign_to_seat_group = {"pass"},
	visual_size = {x=1, y=1},
	wagon_span=2.5,
	collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
	drops={"default:steelblock 4"},
}

if advtrains_attachment_offset_patch then
	compartment_def.seats[1].attach_offset = vector.new(2, -1, 12.5)
	compartment_def.seats[1].view_offset   = vector.new(0, -2, 0.5)

	compartment_def.seats[2].attach_offset = vector.new(2, -1, 4.5)
	compartment_def.seats[2].view_offset   = vector.new(0, -2, 0.5)

	compartment_def.seats[3].attach_offset = vector.new(2, -1, -3.5)
	compartment_def.seats[3].view_offset   = vector.new(0, -2, 0.5)

	compartment_def.seats[4].attach_offset = vector.new(2, -1, -11.5)
	compartment_def.seats[4].view_offset   = vector.new(0, -2, 0.5)

	advtrains_attachment_offset_patch.setup_advtrains_wagon(compartment_def)
end

advtrains.register_wagon("wagon_compartment", compartment_def,
	S("Passenger compartment Wagon"), "advtrains_compartment_inv.png") 


-- Restored wagon (compartments removed)
local restored_def = table.copy(compartment_def)
restored_def.mesh = "advtrains_wagon_compartment.b3d"
restored_def.textures = {"advtrains_orient_express_restored.png"}
-- This may not be necessary given the table copy above, but I want to use the
-- API "correctly" in case of changes. Calling twice is okay since the API is
-- idempotent.
if advtrains_attachment_offset_patch then
	advtrains_attachment_offset_patch.setup_advtrains_wagon(restored_def)

end

advtrains.register_wagon("wagon_compartment_restored", restored_def, 
	S("Passenger Restored Wagon"), "advtrains_orient_express_restored_inv.png") 

-- Sleeper wagon
local sleep_def = table.copy(compartment_def)
sleep_def.mesh = "advtrains_wagon_sleep.b3d"
sleep_def.textures = {"advtrains_sleep.png"}
if advtrains_attachment_offset_patch then
	sleep_def.seats[1].attach_offset = vector.new(-2, 8, 12.1)
	sleep_def.seats[1].view_offset   = vector.new(0, -12, -4)
	sleep_def.seats[1].advtrains_attachment_offset_patch_attach_rotation = vector.new(-90,-90,0)
	
	sleep_def.seats[2].attach_offset = vector.new(-2, 8, 4.1)
	sleep_def.seats[2].view_offset   = vector.new(0, -12, -4)
	sleep_def.seats[2].advtrains_attachment_offset_patch_attach_rotation = vector.new(-90,-90,0)

	sleep_def.seats[3].attach_offset = vector.new(-2, 8, -4.1)
	sleep_def.seats[3].view_offset   = vector.new(0, -12, -4)
	sleep_def.seats[3].advtrains_attachment_offset_patch_attach_rotation = vector.new(-90,-90,0)

	sleep_def.seats[4].attach_offset = vector.new(-2, 8, -12.4)
	sleep_def.seats[4].view_offset   = vector.new(0, -12, -4)
	sleep_def.seats[4].advtrains_attachment_offset_patch_attach_rotation = vector.new(-90,-90,0)

	advtrains_attachment_offset_patch.setup_advtrains_wagon(sleep_def)

	local old_get_on = sleep_def.get_on
	sleep_def.get_on = function(self, clicker, seatno, ...)
		if not clicker then return end
		local data = advtrains.wagons[self.id]
		_old_scale = clicker:get_properties().visual_size
		clicker:set_properties({visual_size = vector.new(0.5,0.5,0.5)})
		local pmeta = clicker:get_meta()
		pmeta:set_float("_advt_old_visual_x", _old_scale.x)
		pmeta:set_float("_advt_old_visual_y", _old_scale.y)
		pmeta:set_float("_advt_old_visual_z", _old_scale.z)
		old_get_on(self, clicker, seatno, ...)
	end

	-- I sure hope there's no way for the player to get out of the wagon
	-- without the get_off callback
	local old_get_off = sleep_def.get_off
	sleep_def.get_off = function(self, seatno, ...)
		local data = advtrains.wagons[self.id]
		if not data.seatp[seatno] then return end
		local pname = data.seatp[seatno]
		local player = core.get_player_by_name(pname)
		local pmeta = player:get_meta()
		local vis_x = pmeta:get_float("_advt_old_visual_x")
		local vis_y = pmeta:get_float("_advt_old_visual_y")
		local vis_z = pmeta:get_float("_advt_old_visual_z")
		-- No data present, gone wrong
		if vis_x == 0 and vis_y == 0 and vis_z == 0 then
			vis = vector.new(1,1,1)
		else
			vis = vector.new(vis_x, vis_y, vis_z)
		end
		player:set_properties({visual_size = vis})
		if not player then return end
		old_get_off(self, seatno, ...)
	end
end

-- FIXME: The last player to join will not be scaled correctly if they are
-- logging back in to a wagon. advtrains_attachment_offset modpack README
-- describes a bug in the on_joinplayer - this may be related

advtrains.register_wagon("wagon_sleep", sleep_def, 
	S("Passenger sleeping Wagon"), "advtrains_sleep_inv.png") 
